<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
        "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="../Styles/sure3.css" rel="stylesheet" type="text/css"/>
    <link href="../Styles/base1.css" rel="stylesheet" type="text/css"/>
</head>

<body>
<div class="markdown-body entry-content" itemprop="text">
    <h1><a href="#编程风格"  class="anchor" id="user-content-编程风格">

    </a>编程风格
    </h1>
    <p>本章探讨如何将 ES6 的新语法，运用到编码实践之中，与传统的 JavaScript 语法结合在一起，写出合理的、易于阅读和维护的代码。</p>
    <p>多家公司和组织已经公开了它们的风格规范，下面的内容主要参考了 <a href="https://github.com/airbnb/javascript">Airbnb</a> 公司的 JavaScript 风格规范。</p>
    <h2><a href="#块级作用域"  class="anchor" id="user-content-块级作用域">

    </a>块级作用域
    </h2>
    <p><strong>（1）let 取代 var</strong></p>
    <p>ES6
        提出了两个新的声明变量的命令：<code>let</code>和<code>const</code>。其中，<code>let</code>完全可以取代<code>var</code>，因为两者语义相同，而且<code>let</code>没有副作用。
    </p>
    <div class="highlight highlight-source-js"><pre><span class="pl-s"><span class="pl-pds">'</span>use strict<span
            class="pl-pds">'</span></span>;

<span class="pl-k">if</span> (<span class="pl-c1">true</span>) {
  <span class="pl-k">let</span> x <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>hello<span
                class="pl-pds">'</span></span>;
}

<span class="pl-k">for</span> (<span class="pl-k">let</span> i <span class="pl-k">=</span> <span class="pl-c1">0</span>; i <span
                class="pl-k">&lt;</span> <span class="pl-c1">10</span>; i<span class="pl-k">++</span>) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(i);
}</pre>
    </div>
    <p>上面代码如果用<code>var</code>替代<code>let</code>，实际上就声明了两个全局变量，这显然不是本意。变量应该只在其声明的代码块内有效，<code>var</code>命令做不到这一点。</p>
    <p><code>var</code>命令存在变量提升效用，<code>let</code>命令没有这个问题。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-s"><span class="pl-pds">'</span>use strict<span
            class="pl-pds">'</span></span>;

<span class="pl-k">if</span> (<span class="pl-c1">true</span>) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(x); <span class="pl-c"><span class="pl-c">//</span> ReferenceError</span>
  <span class="pl-k">let</span> x <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>hello<span
                class="pl-pds">'</span></span>;
}</pre>
    </div>
    <p>上面代码如果使用<code>var</code>替代<code>let</code>，<code>console.log</code>那一行就不会报错，而是会输出<code>undefined</code>，因为变量声明提升到代码块的头部。这违反了变量先声明后使用的原则。
    </p>
    <p>所以，建议不再使用<code>var</code>命令，而是使用<code>let</code>命令取代。</p>
    <p><strong>（2）全局常量和线程安全</strong></p>
    <p>在<code>let</code>和<code>const</code>之间，建议优先使用<code>const</code>，尤其是在全局环境，不应该设置变量，只应设置常量。</p>
    <p><code>const</code>优于<code>let</code>有几个原因。一个是<code>const</code>可以提醒阅读程序的人，这个变量不应该改变；另一个是<code>const</code>比较符合函数式编程思想，运算不改变值，只是新建值，而且这样也有利于将来的分布式运算；最后一个原因是
        JavaScript
        编译器会对<code>const</code>进行优化，所以多使用<code>const</code>，有利于提供程序的运行效率，也就是说<code>let</code>和<code>const</code>的本质区别，其实是编译器内部的处理不同。
    </p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">var</span> a <span class="pl-k">=</span> <span class="pl-c1">1</span>, b <span class="pl-k">=</span> <span
                class="pl-c1">2</span>, c <span class="pl-k">=</span> <span class="pl-c1">3</span>;

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">const</span> <span class="pl-c1">a</span> <span class="pl-k">=</span> <span class="pl-c1">1</span>;
<span class="pl-k">const</span> <span class="pl-c1">b</span> <span class="pl-k">=</span> <span class="pl-c1">2</span>;
<span class="pl-k">const</span> <span class="pl-c1">c</span> <span class="pl-k">=</span> <span class="pl-c1">3</span>;

<span class="pl-c"><span class="pl-c">//</span> best</span>
<span class="pl-k">const</span> [<span class="pl-c1">a</span>, <span class="pl-c1">b</span>, <span
                class="pl-c1">c</span>] <span class="pl-k">=</span> [<span class="pl-c1">1</span>, <span
                class="pl-c1">2</span>, <span class="pl-c1">3</span>];</pre>
    </div>
    <p><code>const</code>声明常量还有两个好处，一是阅读代码的人立刻会意识到不应该修改这个值，二是防止了无意间修改变量值所导致的错误。</p>
    <p>所有的函数都应该设置为常量。</p>
    <p>长远来看，JavaScript 可能会有多线程的实现（比如 Intel 公司的 River Trail 那一类的项目），这时<code>let</code>表示的变量，只应出现在单线程运行的代码中，不能是多线程共享的，这样有利于保证线程安全。
    </p>
    <h2><a href="#字符串"  class="anchor" id="user-content-字符串">

    </a>字符串
    </h2>
    <p>静态字符串一律使用单引号或反引号，不使用双引号。动态字符串使用反引号。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">const</span> <span class="pl-c1">a</span> <span class="pl-k">=</span> <span class="pl-s"><span
                class="pl-pds">"</span>foobar<span class="pl-pds">"</span></span>;
<span class="pl-k">const</span> <span class="pl-c1">b</span> <span class="pl-k">=</span> <span class="pl-s"><span
                class="pl-pds">'</span>foo<span class="pl-pds">'</span></span> <span class="pl-k">+</span> a <span
                class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">'</span>bar<span
                class="pl-pds">'</span></span>;

<span class="pl-c"><span class="pl-c">//</span> acceptable</span>
<span class="pl-k">const</span> <span class="pl-c1">c</span> <span class="pl-k">=</span> <span class="pl-s"><span
                class="pl-pds">`</span>foobar<span class="pl-pds">`</span></span>;

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">const</span> <span class="pl-c1">a</span> <span class="pl-k">=</span> <span class="pl-s"><span
                class="pl-pds">'</span>foobar<span class="pl-pds">'</span></span>;
<span class="pl-k">const</span> <span class="pl-c1">b</span> <span class="pl-k">=</span> <span class="pl-s"><span
                class="pl-pds">`</span>foo<span class="pl-s1"><span class="pl-pse">${</span>a<span
                class="pl-pse">}</span></span>bar<span class="pl-pds">`</span></span>;
<span class="pl-k">const</span> <span class="pl-c1">c</span> <span class="pl-k">=</span> <span class="pl-s"><span
                class="pl-pds">'</span>foobar<span class="pl-pds">'</span></span>;</pre>
    </div>
    <h2><a href="#解构赋值"  class="anchor" id="user-content-解构赋值">

    </a>解构赋值
    </h2>
    <p>使用数组成员对变量赋值时，优先使用解构赋值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">arr</span> <span
            class="pl-k">=</span> [<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span
            class="pl-c1">3</span>, <span class="pl-c1">4</span>];

<span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">const</span> <span class="pl-c1">first</span> <span class="pl-k">=</span> arr[<span
                class="pl-c1">0</span>];
<span class="pl-k">const</span> <span class="pl-c1">second</span> <span class="pl-k">=</span> arr[<span
                class="pl-c1">1</span>];

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">const</span> [<span class="pl-c1">first</span>, <span class="pl-c1">second</span>] <span
                class="pl-k">=</span> arr;</pre>
    </div>
    <p>函数的参数如果是对象的成员，优先使用解构赋值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">function</span> <span class="pl-en">getFullName</span>(<span class="pl-smi">user</span>) {
  <span class="pl-k">const</span> <span class="pl-c1">firstName</span> <span class="pl-k">=</span> <span class="pl-smi">user</span>.<span
                class="pl-smi">firstName</span>;
  <span class="pl-k">const</span> <span class="pl-c1">lastName</span> <span class="pl-k">=</span> <span class="pl-smi">user</span>.<span
                class="pl-smi">lastName</span>;
}

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">function</span> <span class="pl-en">getFullName</span>(<span class="pl-smi">obj</span>) {
  <span class="pl-k">const</span> { <span class="pl-c1">firstName</span>, <span class="pl-c1">lastName</span> } <span
                class="pl-k">=</span> obj;
}

<span class="pl-c"><span class="pl-c">//</span> best</span>
<span class="pl-k">function</span> <span class="pl-en">getFullName</span>({ firstName, lastName }) {
}</pre>
    </div>
    <p>如果函数返回多个值，优先使用对象的解构赋值，而不是数组的解构赋值。这样便于以后添加返回值，以及更改返回值的顺序。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">function</span> <span class="pl-en">processInput</span>(<span class="pl-smi">input</span>) {
  <span class="pl-k">return</span> [left, right, top, bottom];
}

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">function</span> <span class="pl-en">processInput</span>(<span class="pl-smi">input</span>) {
  <span class="pl-k">return</span> { left, right, top, bottom };
}

<span class="pl-k">const</span> { <span class="pl-c1">left</span>, <span class="pl-c1">right</span> } <span
                class="pl-k">=</span> <span class="pl-en">processInput</span>(input);</pre>
    </div>
    <h2><a href="#对象"  class="anchor" id="user-content-对象">

    </a>对象
    </h2>
    <p>单行定义的对象，最后一个成员不以逗号结尾。多行定义的对象，最后一个成员以逗号结尾。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">const</span> <span class="pl-c1">a</span> <span class="pl-k">=</span> { k1<span class="pl-k">:</span> v1, k2<span
                class="pl-k">:</span> v2, };
<span class="pl-k">const</span> <span class="pl-c1">b</span> <span class="pl-k">=</span> {
  k1<span class="pl-k">:</span> v1,
  k2<span class="pl-k">:</span> v2
};

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">const</span> <span class="pl-c1">a</span> <span class="pl-k">=</span> { k1<span class="pl-k">:</span> v1, k2<span
                class="pl-k">:</span> v2 };
<span class="pl-k">const</span> <span class="pl-c1">b</span> <span class="pl-k">=</span> {
  k1<span class="pl-k">:</span> v1,
  k2<span class="pl-k">:</span> v2,
};</pre>
    </div>
    <p>对象尽量静态化，一旦定义，就不得随意添加新的属性。如果添加属性不可避免，要使用<code>Object.assign</code>方法。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">const</span> <span class="pl-c1">a</span> <span class="pl-k">=</span> {};
<span class="pl-smi">a</span>.<span class="pl-c1">x</span> <span class="pl-k">=</span> <span class="pl-c1">3</span>;

<span class="pl-c"><span class="pl-c">//</span> if reshape unavoidable</span>
<span class="pl-k">const</span> <span class="pl-c1">a</span> <span class="pl-k">=</span> {};
<span class="pl-c1">Object</span>.<span class="pl-en">assign</span>(a, { x<span class="pl-k">:</span> <span
                class="pl-c1">3</span> });

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">const</span> <span class="pl-c1">a</span> <span class="pl-k">=</span> { x<span class="pl-k">:</span> <span
                class="pl-c1">null</span> };
<span class="pl-smi">a</span>.<span class="pl-c1">x</span> <span class="pl-k">=</span> <span
                class="pl-c1">3</span>;</pre>
    </div>
    <p>如果对象的属性名是动态的，可以在创造对象的时候，使用属性表达式定义。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">const</span> <span class="pl-c1">obj</span> <span class="pl-k">=</span> {
  id<span class="pl-k">:</span> <span class="pl-c1">5</span>,
  name<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>San Francisco<span
                class="pl-pds">'</span></span>,
};
obj[<span class="pl-en">getKey</span>(<span class="pl-s"><span class="pl-pds">'</span>enabled<span
                class="pl-pds">'</span></span>)] <span class="pl-k">=</span> <span class="pl-c1">true</span>;

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">const</span> <span class="pl-c1">obj</span> <span class="pl-k">=</span> {
  id<span class="pl-k">:</span> <span class="pl-c1">5</span>,
  name<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>San Francisco<span
                class="pl-pds">'</span></span>,
  [<span class="pl-en">getKey</span>(<span class="pl-s"><span class="pl-pds">'</span>enabled<span
                class="pl-pds">'</span></span>)]<span class="pl-k">:</span> <span class="pl-c1">true</span>,
};</pre>
    </div>
    <p>上面代码中，对象<code>obj</code>的最后一个属性名，需要计算得到。这时最好采用属性表达式，在新建<code>obj</code>的时候，将该属性与其他属性定义在一起。这样一来，所有属性就在一个地方定义了。</p>
    <p>另外，对象的属性和方法，尽量采用简洁表达法，这样易于描述和书写。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> ref <span class="pl-k">=</span> <span
            class="pl-s"><span class="pl-pds">'</span>some value<span class="pl-pds">'</span></span>;

<span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">const</span> <span class="pl-c1">atom</span> <span class="pl-k">=</span> {
  ref<span class="pl-k">:</span> ref,

  value<span class="pl-k">:</span> <span class="pl-c1">1</span>,

  <span class="pl-en">addValue</span><span class="pl-k">:</span> <span class="pl-k">function</span> (<span
                class="pl-smi">value</span>) {
    <span class="pl-k">return</span> <span class="pl-smi">atom</span>.<span class="pl-c1">value</span> <span
                class="pl-k">+</span> value;
  },
};

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">const</span> <span class="pl-c1">atom</span> <span class="pl-k">=</span> {
  ref,

  value<span class="pl-k">:</span> <span class="pl-c1">1</span>,

  <span class="pl-en">addValue</span>(<span class="pl-smi">value</span>) {
    <span class="pl-k">return</span> <span class="pl-smi">atom</span>.<span class="pl-c1">value</span> <span
                class="pl-k">+</span> value;
  },
};</pre>
    </div>
    <h2><a href="#数组"  class="anchor" id="user-content-数组">

    </a>数组
    </h2>
    <p>使用扩展运算符（...）拷贝数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">const</span> <span class="pl-c1">len</span> <span class="pl-k">=</span> <span
                class="pl-smi">items</span>.<span class="pl-c1">length</span>;
<span class="pl-k">const</span> <span class="pl-c1">itemsCopy</span> <span class="pl-k">=</span> [];
<span class="pl-k">let</span> i;

<span class="pl-k">for</span> (i <span class="pl-k">=</span> <span class="pl-c1">0</span>; i <span
                class="pl-k">&lt;</span> len; i<span class="pl-k">++</span>) {
  itemsCopy[i] <span class="pl-k">=</span> items[i];
}

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">const</span> <span class="pl-c1">itemsCopy</span> <span class="pl-k">=</span> [<span
                class="pl-k">...</span>items];</pre>
    </div>
    <p>使用 Array.from 方法，将类似数组的对象转为数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">foo</span> <span
            class="pl-k">=</span> <span class="pl-c1">document</span>.<span class="pl-c1">querySelectorAll</span>(<span
            class="pl-s"><span class="pl-pds">'</span>.foo<span class="pl-pds">'</span></span>);
<span class="pl-k">const</span> <span class="pl-c1">nodes</span> <span class="pl-k">=</span> <span
                class="pl-c1">Array</span>.<span class="pl-en">from</span>(foo);</pre>
    </div>
    <h2><a href="#函数"  class="anchor" id="user-content-函数">

    </a>函数
    </h2>
    <p>立即执行函数可以写成箭头函数的形式。</p>
    <div class="highlight highlight-source-js"><pre>(() <span class="pl-k">=&gt;</span> {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>Welcome to the Internet.<span
                class="pl-pds">'</span></span>);
})();</pre>
    </div>
    <p>那些需要使用函数表达式的场合，尽量用箭头函数代替。因为这样更简洁，而且绑定了 this。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>].<span
                class="pl-en">map</span>(<span class="pl-k">function</span> (<span class="pl-smi">x</span>) {
  <span class="pl-k">return</span> x <span class="pl-k">*</span> x;
});

<span class="pl-c"><span class="pl-c">//</span> good</span>
[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>].<span
                class="pl-en">map</span>((<span class="pl-smi">x</span>) <span class="pl-k">=&gt;</span> {
  <span class="pl-k">return</span> x <span class="pl-k">*</span> x;
});

<span class="pl-c"><span class="pl-c">//</span> best</span>
[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>].<span
                class="pl-en">map</span>(<span class="pl-smi">x</span> <span class="pl-k">=&gt;</span> x <span
                class="pl-k">*</span> x);</pre>
    </div>
    <p>箭头函数取代<code>Function.prototype.bind</code>，不应再用 self/_this/that 绑定 this。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">const</span> <span class="pl-c1">self</span> <span class="pl-k">=</span> <span
                class="pl-c1">this</span>;
<span class="pl-k">const</span> <span class="pl-c1">boundMethod</span> <span class="pl-k">=</span> <span class="pl-k">function</span>(<span
                class="pl-k">...</span><span class="pl-v">params</span>) {
  <span class="pl-k">return</span> <span class="pl-smi">method</span>.<span class="pl-c1">apply</span>(self, params);
}

<span class="pl-c"><span class="pl-c">//</span> acceptable</span>
<span class="pl-k">const</span> <span class="pl-c1">boundMethod</span> <span class="pl-k">=</span> <span class="pl-smi">method</span>.<span
                class="pl-en">bind</span>(<span class="pl-c1">this</span>);

<span class="pl-c"><span class="pl-c">//</span> best</span>
<span class="pl-k">const</span> <span class="pl-c1">boundMethod</span> <span class="pl-k">=</span> (<span class="pl-k">...</span><span
                class="pl-v">params</span>) <span class="pl-k">=&gt;</span> <span class="pl-smi">method</span>.<span
                class="pl-c1">apply</span>(<span class="pl-c1">this</span>, params);</pre>
    </div>
    <p>简单的、单行的、不会复用的函数，建议采用箭头函数。如果函数体较为复杂，行数较多，还是应该采用传统的函数写法。</p>
    <p>所有配置项都应该集中在一个对象，放在最后一个参数，布尔值不可以直接作为参数。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">function</span> <span class="pl-en">divide</span>(<span class="pl-smi">a</span>, <span
                class="pl-smi">b</span>, <span class="pl-smi">option</span> <span class="pl-k">=</span> <span
                class="pl-c1">false</span> ) {
}

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">function</span> <span class="pl-en">divide</span>(<span class="pl-smi">a</span>, <span
                class="pl-smi">b</span>, { option <span class="pl-k">=</span> <span class="pl-c1">false</span> } <span
                class="pl-k">=</span> {}) {
}</pre>
    </div>
    <p>不要在函数体内使用 arguments 变量，使用 rest 运算符（...）代替。因为 rest 运算符显式表明你想要获取参数，而且 arguments 是一个类似数组的对象，而 rest
        运算符可以提供一个真正的数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">function</span> <span class="pl-en">concatenateAll</span>() {
  <span class="pl-k">const</span> <span class="pl-c1">args</span> <span class="pl-k">=</span> <span
                class="pl-c1">Array</span>.<span class="pl-c1">prototype</span>.<span class="pl-smi">slice</span>.<span
                class="pl-c1">call</span>(<span class="pl-c1">arguments</span>);
  <span class="pl-k">return</span> <span class="pl-smi">args</span>.<span class="pl-c1">join</span>(<span
                class="pl-s"><span class="pl-pds">'</span><span class="pl-pds">'</span></span>);
}

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">function</span> <span class="pl-en">concatenateAll</span>(<span class="pl-k">...</span><span
                class="pl-v">args</span>) {
  <span class="pl-k">return</span> <span class="pl-smi">args</span>.<span class="pl-c1">join</span>(<span
                class="pl-s"><span class="pl-pds">'</span><span class="pl-pds">'</span></span>);
}</pre>
    </div>
    <p>使用默认值语法设置函数参数的默认值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">function</span> <span class="pl-en">handleThings</span>(<span class="pl-smi">opts</span>) {
  opts <span class="pl-k">=</span> opts <span class="pl-k">||</span> {};
}

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">function</span> <span class="pl-en">handleThings</span>(<span class="pl-smi">opts</span> <span
                class="pl-k">=</span> {}) {
  <span class="pl-c"><span class="pl-c">//</span> ...</span>
}</pre>
    </div>
    <h2><a href="#map-结构"  class="anchor" id="user-content-map-结构">

    </a>Map 结构
    </h2>
    <p>注意区分 Object 和 Map，只有模拟现实世界的实体对象时，才使用 Object。如果只是需要<code>key: value</code>的数据结构，使用 Map 结构。因为 Map 有内建的遍历机制。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> map <span class="pl-k">=</span> <span
            class="pl-k">new</span> <span class="pl-en">Map</span>(arr);

<span class="pl-k">for</span> (<span class="pl-k">let</span> key <span class="pl-k">of</span> <span
                class="pl-smi">map</span>.<span class="pl-c1">keys</span>()) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(key);
}

<span class="pl-k">for</span> (<span class="pl-k">let</span> value <span class="pl-k">of</span> <span
                class="pl-smi">map</span>.<span class="pl-c1">values</span>()) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(value);
}

<span class="pl-k">for</span> (<span class="pl-k">let</span> item <span class="pl-k">of</span> <span
                class="pl-smi">map</span>.<span class="pl-c1">entries</span>()) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(item[<span class="pl-c1">0</span>], item[<span
                class="pl-c1">1</span>]);
}</pre>
    </div>
    <h2><a href="#class"  class="anchor" id="user-content-class">

    </a>Class
    </h2>
    <p>总是用 Class，取代需要 prototype 的操作。因为 Class 的写法更简洁，更易于理解。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">function</span> <span class="pl-en">Queue</span>(<span class="pl-smi">contents</span> <span
                class="pl-k">=</span> []) {
  <span class="pl-c1">this</span>.<span class="pl-smi">_queue</span> <span class="pl-k">=</span> [<span
                class="pl-k">...</span>contents];
}
<span class="pl-smi">Queue</span>.<span class="pl-c1">prototype</span>.<span class="pl-en">pop</span> <span
                class="pl-k">=</span> <span class="pl-k">function</span>() {
  <span class="pl-k">const</span> <span class="pl-c1">value</span> <span class="pl-k">=</span> <span
                class="pl-c1">this</span>.<span class="pl-smi">_queue</span>[<span class="pl-c1">0</span>];
  <span class="pl-c1">this</span>.<span class="pl-smi">_queue</span>.<span class="pl-c1">splice</span>(<span
                class="pl-c1">0</span>, <span class="pl-c1">1</span>);
  <span class="pl-k">return</span> value;
}

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">class</span> <span class="pl-en">Queue</span> {
  <span class="pl-en">constructor</span>(<span class="pl-smi">contents</span> <span class="pl-k">=</span> []) {
    <span class="pl-c1">this</span>.<span class="pl-smi">_queue</span> <span class="pl-k">=</span> [<span class="pl-k">...</span>contents];
  }
  <span class="pl-en">pop</span>() {
    <span class="pl-k">const</span> <span class="pl-c1">value</span> <span class="pl-k">=</span> <span class="pl-c1">this</span>.<span
                class="pl-smi">_queue</span>[<span class="pl-c1">0</span>];
    <span class="pl-c1">this</span>.<span class="pl-smi">_queue</span>.<span class="pl-c1">splice</span>(<span
                class="pl-c1">0</span>, <span class="pl-c1">1</span>);
    <span class="pl-k">return</span> value;
  }
}</pre>
    </div>
    <p>使用<code>extends</code>实现继承，因为这样更简单，不会有破坏<code>instanceof</code>运算的危险。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">const</span> <span class="pl-c1">inherits</span> <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span
                class="pl-s"><span class="pl-pds">'</span>inherits<span class="pl-pds">'</span></span>);
<span class="pl-k">function</span> <span class="pl-en">PeekableQueue</span>(<span class="pl-smi">contents</span>) {
  <span class="pl-smi">Queue</span>.<span class="pl-c1">apply</span>(<span class="pl-c1">this</span>, contents);
}
<span class="pl-en">inherits</span>(PeekableQueue, Queue);
<span class="pl-smi">PeekableQueue</span>.<span class="pl-c1">prototype</span>.<span class="pl-en">peek</span> <span
                class="pl-k">=</span> <span class="pl-k">function</span>() {
  <span class="pl-k">return</span> <span class="pl-c1">this</span>.<span class="pl-smi">_queue</span>[<span
                class="pl-c1">0</span>];
}

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">class</span> <span class="pl-en">PeekableQueue</span> <span class="pl-k">extends</span> <span
                class="pl-e">Queue</span> {
  <span class="pl-en">peek</span>() {
    <span class="pl-k">return</span> <span class="pl-c1">this</span>.<span class="pl-smi">_queue</span>[<span
                class="pl-c1">0</span>];
  }
}</pre>
    </div>
    <h2><a href="#模块"  class="anchor" id="user-content-模块">

    </a>模块
    </h2>
    <p>首先，Module 语法是 JavaScript 模块的标准写法，坚持使用这种写法。使用<code>import</code>取代<code>require</code>。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">const</span> <span class="pl-c1">moduleA</span> <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span
                class="pl-s"><span class="pl-pds">'</span>moduleA<span class="pl-pds">'</span></span>);
<span class="pl-k">const</span> <span class="pl-c1">func1</span> <span class="pl-k">=</span> <span class="pl-smi">moduleA</span>.<span
                class="pl-smi">func1</span>;
<span class="pl-k">const</span> <span class="pl-c1">func2</span> <span class="pl-k">=</span> <span class="pl-smi">moduleA</span>.<span
                class="pl-smi">func2</span>;

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">import</span> { <span class="pl-smi">func1</span>, <span class="pl-smi">func2</span> } <span
                class="pl-k">from</span> <span class="pl-s"><span class="pl-pds">'</span>moduleA<span
                class="pl-pds">'</span></span>;</pre>
    </div>
    <p>使用<code>export</code>取代<code>module.exports</code>。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> commonJS的写法</span>
<span class="pl-k">var</span> React <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span
                class="pl-s"><span class="pl-pds">'</span>react<span class="pl-pds">'</span></span>);

<span class="pl-k">var</span> Breadcrumbs <span class="pl-k">=</span> <span class="pl-smi">React</span>.<span
                class="pl-en">createClass</span>({
  <span class="pl-en">render</span>() {
    <span class="pl-k">return</span> <span class="pl-k">&lt;</span>nav <span class="pl-k">/</span><span class="pl-k">&gt;</span>;
  }
});

<span class="pl-c1">module</span>.<span class="pl-smi">exports</span> <span class="pl-k">=</span> Breadcrumbs;

<span class="pl-c"><span class="pl-c">//</span> ES6的写法</span>
<span class="pl-k">import</span> <span class="pl-smi">React</span> <span class="pl-k">from</span> <span
                class="pl-s"><span class="pl-pds">'</span>react<span class="pl-pds">'</span></span>;

<span class="pl-k">class</span> <span class="pl-en">Breadcrumbs</span> <span class="pl-k">extends</span> <span
                class="pl-e">React</span>.<span class="pl-smi">Component</span> {
  <span class="pl-en">render</span>() {
    <span class="pl-k">return</span> <span class="pl-k">&lt;</span>nav <span class="pl-k">/</span><span class="pl-k">&gt;</span>;
  }
};

<span class="pl-k">export</span> <span class="pl-c1">default</span> <span class="pl-smi">Breadcrumbs</span>;</pre>
    </div>
    <p>如果模块只有一个输出值，就使用<code>export default</code>，如果模块有多个输出值，就不使用<code>export default</code>，<code>export default</code>与普通的<code>export</code>不要同时使用。
    </p>
    <p>不要在模块输入中使用通配符。因为这样可以确保你的模块之中，有一个默认输出（export default）。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> bad</span>
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span
                class="pl-smi">myObject</span> <span class="pl-k">from</span> <span class="pl-s"><span
                class="pl-pds">'</span>./importModule<span class="pl-pds">'</span></span>;

<span class="pl-c"><span class="pl-c">//</span> good</span>
<span class="pl-k">import</span> <span class="pl-smi">myObject</span> <span class="pl-k">from</span> <span class="pl-s"><span
                class="pl-pds">'</span>./importModule<span class="pl-pds">'</span></span>;</pre>
    </div>
    <p>如果模块默认输出一个函数，函数名的首字母应该小写。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">makeStyleGuide</span>() {
}

<span class="pl-k">export</span> <span class="pl-c1">default</span> <span class="pl-smi">makeStyleGuide</span>;</pre>
    </div>
    <p>如果模块默认输出一个对象，对象名的首字母应该大写。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span
            class="pl-c1">StyleGuide</span> <span class="pl-k">=</span> {
  es6<span class="pl-k">:</span> {
  }
};

<span class="pl-k">export</span> <span class="pl-c1">default</span> <span class="pl-smi">StyleGuide</span>;</pre>
    </div>
    <h2><a href="#eslint-的使用"  class="anchor" id="user-content-eslint-的使用">

    </a>ESLint 的使用
    </h2>
    <p>ESLint 是一个语法规则和代码风格的检查工具，可以用来保证写出语法正确、风格统一的代码。</p>
    <p>首先，安装 ESLint。</p>
    <div class="highlight highlight-source-shell">
        <pre>$ npm i -g eslint</pre>
    </div>
    <p>然后，安装 Airbnb 语法规则，以及 import、a11y、react 插件。</p>
    <div class="highlight highlight-source-shell"><pre>$ npm i -g eslint-config-airbnb
$ npm i -g eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react</pre>
    </div>
    <p>最后，在项目的根目录下新建一个<code>.eslintrc</code>文件，配置 ESLint。</p>
    <div class="highlight highlight-source-js"><pre>{
  <span class="pl-s"><span class="pl-pds">"</span>extends<span class="pl-pds">"</span></span><span class="pl-k">:</span> <span
                class="pl-s"><span class="pl-pds">"</span>eslint-config-airbnb<span class="pl-pds">"</span></span>
}</pre>
    </div>
    <p>现在就可以检查，当前项目的代码是否符合预设的规则。</p>
    <p><code>index.js</code>文件的代码如下。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> unusued <span
            class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>I have no purpose!<span
            class="pl-pds">'</span></span>;

<span class="pl-k">function</span> <span class="pl-en">greet</span>() {
    <span class="pl-k">var</span> message <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>Hello, World!<span
                class="pl-pds">'</span></span>;
    <span class="pl-en">alert</span>(message);
}

<span class="pl-en">greet</span>();</pre>
    </div>
    <p>使用 ESLint 检查这个文件，就会报出错误。</p>
    <div class="highlight highlight-source-shell"><pre>$ eslint index.js
index.js
  1:1  error  Unexpected var, use <span class="pl-c1">let</span> or const instead          no-var
  1:5  error  unusued is defined but never used                 no-unused-vars
  4:5  error  Expected indentation of 2 characters but found 4  indent
  4:5  error  Unexpected var, use <span class="pl-c1">let</span> or const instead          no-var
  5:5  error  Expected indentation of 2 characters but found 4  indent

✖ 5 problems (5 errors, 0 warnings)</pre>
    </div>
    <p>上面代码说明，原文件有五个错误，其中两个是不应该使用<code>var</code>命令，而要使用<code>let</code>或<code>const</code>；一个是定义了变量，却没有使用；另外两个是行首缩进为 4
        个空格，而不是规定的 2 个空格。</p>
</div>
</body>
</html>
